(function(K) {
	
K.classLoader().
includes("K.lang.Function").
requires("K.lang.Reflect").
provides("K.lang.Array").
load(function(I, S) {
	var AP = Array.prototype,
	
		nativeFunction = function(functionName) {
	        return function(a) {
	            return AP[functionName].apply(a, AP.slice.call(arguments, 1)); 
	        };
		};
	
	return {
		asArray : function(a) {
			return AP.slice.call(a);
		},
		
		filter : (function() {
			if (I.Reflect.isFunction(AP.filter)) {
				return nativeFunction("filter");
			}
			
			return function(array, callback, thisObject) {
                if (!I.Reflect.isFunction(callback)) {
                    throw new TypeError();
                }
            
                var result = [];
                for (var i = 0, l = array.length >>> 0; i < l; i++) {
                    if (i in array) {
                        var v = array[i];
                        if (callback.call(thisObject, v, i, array)) {
                            result.push(v);
                        }
                    }
                }
            
                return result;				
			};
        }()),
			
		forEach : (function() {
			if (I.Reflect.isFunction(AP.forEach)) {
				return nativeFunction("forEach");
			}
			
			return function(array, callback, thisObject) {
                if (!I.Reflect.isFunction(callback)) {
                    throw new TypeError();
                }
                
                for (var i = 0, l = array.length >>> 0; i < l; i++) {
                    if (i in this) {
                        callback.call(thisObject, array[i], i, array);
                    }
                }
			};
		})(),
		
		every : (function() {
            if (I.Reflect.isFunction(AP.every)) {
                return nativeFunction("every");
            }
            
            return function(array, callback, thisObject) {
                if (!I.Reflect.isFunction(callback)) {
                    throw new TypeError();
                }
            
                for (var i = 0, l = array.length >>> 0; i < l; i++) {
                    if (i in array && !callback.call(thisObject, array[i], i, array)) {
                    	return false;
                    }
                }
            
                return true;            	
            };
            
		})(),
		
		map : (function() {
            if (I.Reflect.isFunction(AP.map)) {
            	return nativeFunction("map");
            }		
            
            return function(array, callback, thisObject) {
                if (!I.Reflect.isFunction(callback)) {
                    throw new TypeError();
                }
                
                var l = array.length >>> 0; 
                var result = new Array(l);
                for (var i = 0; i < l; i++) {
                    if (i in array) {
                    	result[i] = callback.call(thisObject, array[i], i, array);
                    }
                }
                return result;
            };
		})(),
		
        some : (function() {
            if (I.Reflect.isFunction(AP.some)) {
                return nativeFunction("some");
            }
            
            return function(array, callback, thisObject) {
                if (!I.Reflect.isFunction(callback)) {
                    throw new TypeError();
                }
                
                for (var i = 0, l = array.length >>> 0; i < l; i++) {
                    if (i in array && callback.call(thisObject, array[i], i, array)) {
                        return true;
                    }
                }
                return false;
            };
        })(),
		
		
        reduce : (function() {
            if (I.Reflect.isFunction(AP.reduce)) {
            	return nativeFunction("reduce");
            }

            return function(array, callback, initialValue) {
                if (!I.Reflect.isFunction(callback)) {
                    throw new TypeError();
                }
            	
            	var l = array.length >>> 0;
                if (l == 0 && arguments.length == 2) {
                    throw new TypeError();
                }
        
                var i = 0;
                var returnValue = (function(args) {
                	if (args.length >= 3) {
                		return initialValue;
                	}
                    do {
                        if (i in array) {
                            return array[i++];
                        }
                        
                        if (++i >= l) {
                            throw new TypeError();
                        }
                    } while (true);
                })(arguments);
        
                for (; i < l; i++) {
                    if (i in array) {
                        returnValue = callback.call(null, returnValue, array[i], i, array);
                    }
                }
        
                return returnValue;
            };
        })(),
        
        reduceRight : (function() {
            if (I.Reflect.isFunction(AP.reduceRight)) {
            	return nativeFunction("reduceRight");
            }
            
            return function(array, callback, initialValue) {
                if (typeof callback != "function") {
                    throw new TypeError();
                }
            
                var l = array.length >>> 0;
                if (l == 0 && arguments.length == 2) {
                    throw new TypeError();
                }
            
                var i = l - 1;
                var returnValue = (function(args) {
                	if (args.length >= 3) {
                		return initialValue;
                	}
                	
                    do {
                        if (i in array) {
                            return this[i--];
                        }
            
                        if (--i < 0) {
                            throw new TypeError();
                        }
                    } while (true);
                })(arguments);
            
                for (; i >= 0; i--) {
                    if (i in array) { 
                        returnValue = callback.call(null, returnValue, array[i], i, array);
                    }
                }
            
                return returnValue;
            };            
        })(),
        
        indexOf : (function() {
            if (I.Reflect.isFunction(AP.indexOf)) {
                return nativeFunction("indexOf");
            }
            
            return function(array, element, from) {
                var l = array.length >>> 0;
                from = Number(from) || 0;
                from = (from < 0) ? Math.ceil(from) : Math.floor(from);
                if (from < 0) {
                    from += l;
                }
                
                for (; from < l; from++) {
                    if (from in array && array[from] === element) {
                        return from;
                    }
                }
                
                return -1;
              }        	
        })(),
        
        lastIndexOf : (function() {
            if (I.Reflect.isFunction(AP.lastIndexOf)) {
                return nativeFunction("lastIndexOf");
            }
            
            return function(array, element, from) {
                var l = array.length;
            
                from = Number(from);
                if (isNaN(from)) {
                    from = l - 1;
                } else {
                    from = (from < 0) ? Math.ceil(from) : Math.floor(from);
                    if (from < 0) {
                        from += l;
                    } else if (from >= l) {
                        from = l - 1;
                    }
                }
            
                for (; from > -1; from--) {
                    if (from in array && array[from] === element) {
                        return from;
                    }
                }
                return -1;
            };        	
        })()
        
	};	
	
});
	
})(k90tools); 